use async_trait::async_trait;
use clap::Parser;

use crate::commands::commands::Command;
use crate::models::models;
use crate::models::models::command::CommandState;
use crate::utils::command;

#[derive(Debug, Default, Clone, Parser)]
#[clap(disable_help_flag = true)]
struct Args {
    // 字符串长度
    #[arg(short = 'n', long = "number", default_value_t = 10)]
    number: usize,
    // 允许小写字母
    #[arg(short = 'l', long = "lower", default_value_t = false)]
    lower: bool,
    // 允许大写字母
    #[arg(short = 'u', long = "upper", default_value_t = false)]
    upper: bool,
    // 允许符号
    #[arg(short = 's', long = "symbol", default_value_t = false)]
    symbol: bool,
    // 允许数字
    #[arg(short = 'd', long = "digit", default_value_t = false)]
    digit: bool,
    // 自定义字符集
    #[arg(short = 'c', long = "characters", default_value = "")]
    characters: String,
}

#[derive(Debug, Default, Clone)]
pub(crate) struct RandStrCommand {}

#[async_trait]
impl Command for RandStrCommand {
    async fn execute(&self, command: models::command::Command) -> models::command::Command {
        let args = command::parse_command_args::<Args>(command.args.as_str());
        if args.is_err() {
            return self.save_command_output(command, CommandState::Success, args.unwrap_err().to_string());
        }

        let args = args.unwrap();
        let mut builder = &mut randstr::randstr();

        // 设置长度
        builder = builder.len(args.number);

        // 设置自定义字符集
        if !args.characters.is_empty() {
            builder = builder.custom(args.characters.as_str());
            let value = builder.build().generate();

            return self.save_command_output(command, CommandState::Success, value);
        }

        // 允许大写字母
        if args.upper {
            builder = builder.upper();
        }

        // 允许小写字母
        if args.lower {
            builder = builder.lower();
        }

        // 如果未设置大小写标志，默认允许大小写字符
        if !args.upper && !args.lower {
            builder = builder.letter()
        }

        // 允许符号
        if args.symbol {
            builder = builder.symbol();
        }

        // 允许数字
        if args.digit {
            builder = builder.digit();
        }

        let value = builder.build().generate();

        self.save_command_output(command, CommandState::Success, value)
    }
}